﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cotizav.CONEXION;
using System.Transactions;
using System.Windows.Forms;
using Cotizav.CONTROLADOR;
using Cotizav.CONTROLADOR.Otros;
using System.Data;
using System.Data.Linq;

namespace Cotizav
{
    public class CtrlCotizacion
    {
        private ConexionDataContext conexion;
        private CtrlPeriodo ctPeriodo;
        private CtrlCotizacion_Detalle ctCotizacionDetalle;
        private CtrlContactoCotizacion ctContactoCotizacion;
        private CtrlCondicionCotizacion ctCondicionCotizacion;
        private CtrlFormatoCotizacion ctFormatoCotizacion;

        public CtrlCotizacion()
        {
            ctPeriodo = new CtrlPeriodo();
            ctCotizacionDetalle = new CtrlCotizacion_Detalle();
            ctContactoCotizacion = new CtrlContactoCotizacion();
            ctCondicionCotizacion = new CtrlCondicionCotizacion();
            ctFormatoCotizacion = new CtrlFormatoCotizacion();
        }
        
        internal List<COTIZACION> getListCotizacion()
        {
            using (conexion = new ConexionDataContext())
            {
                DataLoadOptions dlo = new DataLoadOptions();
                dlo.LoadWith<COTIZACION>(x => x.CLIENTE);
                conexion.LoadOptions = dlo;
                
                return conexion.COTIZACION.Where(x => x.eliminado == 0).ToList();
            }
        }

        internal COTIZACION getCotizacion(string idCotizacion)
        {
            using (conexion = new ConexionDataContext())
            {
                try
                {
                    return conexion.COTIZACION.SingleOrDefault(x => x.idCotizacion == idCotizacion && x.eliminado == 0);
                }
                catch (Exception)
                {
                    throw;
                }
            }
        }

        internal string registrarCotizacion(COTIZACION cotiz, List<COTIZACION_DETALLE> listCotizacionDetalle, CONTACTO contacto, List<CONDICION> listCondiciones, List<CONDICION> listInformacionAdicional)
        {
            using (TransactionScope transactionscope = new TransactionScope())
            {
                string codigoCotizacion = string.Empty;

                //registramos las cabecera
                using (conexion = new ConexionDataContext())
                {
                    try
                    {
                        int correlativoCotizacion = conexion.COTIZAV_CORRELATIVO.Single(x => x.IDENTIFICADOR == "COTIZAV").COTIZACION.Value;
                        string num = Convert.ToString(correlativoCotizacion);
                        string numero = num.Trim().PadLeft(11, '0');
                        
                        string idCotizacion = "COT_" + numero;
                        codigoCotizacion = this.generaCodigoCotizacion();
                        int numeroCotizacion = Convert.ToInt32(codigoCotizacion.Substring(codigoCotizacion.LastIndexOf('-') + 1));


                        cotiz.idCotizacion = idCotizacion;
                        cotiz.codigoCotizacion = codigoCotizacion;
                        cotiz.numeroCotizacion = numeroCotizacion;

                        conexion.COTIZACION.InsertOnSubmit(cotiz);
                        conexion.SubmitChanges();
                        conexion.increm_ContCotizacion();
                        conexion.increm_NumCotizacionActivo();
                    }
                    catch(Exception)
                    {
                        throw;
                    }
                }

                //registramos el detalle
                using (conexion = new ConexionDataContext())
                {
                    try
                    {
                        int i = 1;
                        foreach (COTIZACION_DETALLE cdetalle in listCotizacionDetalle)
                        {
                            ctCotizacionDetalle.registrarCotizacionDetalle(cdetalle, cotiz, i);
                            i++;
                        }
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }

                //registramos el contacto
                using (conexion = new ConexionDataContext())
                {
                    try
                    {
                        CONTACTO_COTIZACION ccontacto = this.generarContactoCotizacion(contacto);
                        ctContactoCotizacion.registrarContactoCotizacion(ccontacto, cotiz);

                        //List<CONTACTO_COTIZACION> ccontactos = new List<CONTACTO_COTIZACION>();
                        //ccontactos = this.generarListaContactoCotizacion(listContactos);

                        //foreach (CONTACTO_COTIZACION ccon in ccontactos)
                        //{
                        //    ctContactoCotizacion.registrarContactoCotizacion(ccon, cotiz);
                        //}
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }

                //registramos las condiciones
                using (conexion = new ConexionDataContext())
                {
                    try
                    {
                        //unimos la lista de condiciones y de informacion adicional por ser de la misma clase
                        List<CONDICION> ListTempCondiciones = listCondiciones.Union(listInformacionAdicional,new CondicionComparer()).ToList();

                        List<CONDICION_COTIZACION> ccondicion = new List<CONDICION_COTIZACION>();
                        ccondicion = this.generarListaCondicionCotizacion(ListTempCondiciones);

                        foreach (CONDICION_COTIZACION ccond in ccondicion)
                        {
                            ctCondicionCotizacion.registrarCondicionCotizacion(ccond, cotiz);
                        }

                        transactionscope.Complete();
                        return codigoCotizacion;
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
            }
        }

        private string generaCodigoCotizacion()
        {
            string result = string.Empty;

            PERIODO periodo = ctPeriodo.getPeriodoActual();
            int numeroCotizacion = periodo.numeroCotizacion.Value;
            result = "COT" + Convert.ToString(periodo.mesPeriodo).PadLeft(2, '0') +
                       Convert.ToString(periodo.anioPeriodo).Substring(2) + "-" +
                       Convert.ToString(numeroCotizacion).PadLeft(4, '0');

            return result;
        }

        private List<CONTACTO_COTIZACION> generarListaContactoCotizacion(List<CONTACTO> contactos)
        {
            List<CONTACTO_COTIZACION> result = new List<CONTACTO_COTIZACION>();

            foreach (CONTACTO con in contactos)
            {
                CONTACTO_COTIZACION cc = new CONTACTO_COTIZACION()
                {
                    idContacto = con.idContacto,
                    eliminado = 0
                };
                
                result.Add(cc);
            }

            return result;
        }

        private CONTACTO_COTIZACION generarContactoCotizacion(CONTACTO contacto)
        {
            CONTACTO_COTIZACION result = new CONTACTO_COTIZACION()
            {
                idContacto = contacto.idContacto,
                eliminado = 0
            };

            return result;
        }


        private List<CONDICION_COTIZACION> generarListaCondicionCotizacion(List<CONDICION> condiciones)
        {
            List<CONDICION_COTIZACION> result = new List<CONDICION_COTIZACION>();

            foreach (CONDICION cond in condiciones)
            {
                CONDICION_COTIZACION ccd = new CONDICION_COTIZACION()
                {
                    idCondicion = cond.idCondicion,
                    eliminado = 0
                };

                result.Add(ccd);
            }

            return result;
        }

        private List<FORMATO_COTIZACION> generaListaFormatoCotizacion(List<FORMATO> formatos)
        {
            List<FORMATO_COTIZACION> result = new List<FORMATO_COTIZACION>();

            foreach (FORMATO frm in formatos)
            {
                FORMATO_COTIZACION fcc = new FORMATO_COTIZACION()
                {
                    idFormato = frm.idFormato
                };
                
                result.Add(fcc);
            }

            return result;
        }
        
        //internal DataTable getListCotizacion_Visita(string idcliente, string idvendedor)
        //{
        //    using (conexion = new ConexionDataContext())
        //    {
        //        var query = conexion.usp_listarCotizacion_Visita(idcliente, idvendedor);
       
        //        DataTable result = new DataTable();

        //        result.Columns.Add("idCotizacion", Type.GetType("System.String"));
        //        result.Columns.Add("codigocotizacion", Type.GetType("System.String"));
        //        result.Columns.Add("fechaRegistroCotizacion", Type.GetType("System.String"));
        //        result.Columns.Add("idCliente", Type.GetType("System.String"));
        //        result.Columns.Add("nombrecliente", Type.GetType("System.String"));
        //        result.Columns.Add("idVendedor", Type.GetType("System.String"));
        //        result.Columns.Add("nombreVendedor", Type.GetType("System.String"));
        //        result.Columns.Add("idvisita", Type.GetType("System.String"));
        //        result.Columns.Add("estado", Type.GetType("System.String"));
        //        result.Columns.Add("fechavisita", Type.GetType("System.String"));

        //        DataRow dr;

        //        foreach (var c in query)
        //        {
        //            dr = result.NewRow();

        //            dr[0] = c.idcotizacion ?? string.Empty;
        //            dr[1] = c.codigocotizacion ?? string.Empty;
        //            dr[2] = c.FechaRegistroCotizacion != null ? c.FechaRegistroCotizacion.Value.ToShortDateString() : string.Empty;
        //            dr[3] = c.idcliente ?? string.Empty;
        //            dr[4] = c.nombrecliente ?? string.Empty;
        //            dr[5] = c.idvendedor ?? string.Empty;
        //            dr[6] = c.nombrevendedor ?? string.Empty;
        //            dr[7] = c.idvisita ?? string.Empty;
        //            dr[8] = c.estado ?? string.Empty;
        //            dr[9] = c.fechavisita != null ? c.fechavisita.Value.ToShortDateString() : string.Empty;

        //            result.Rows.Add(dr);
        //        }

        //        return result;
        //    }
        //}

        internal DataTable getListCotizacionxClientes(string idCliente, string codigo, char? tipoCotizacion, DateTime? fechaDesde, DateTime? fechaHasta, bool mostrarDetalle)
        {
            DataTable result = new DataTable();

            using (conexion = new ConexionDataContext())
            {
                var query = conexion.usp_listarCotizacionxCliente(idCliente, fechaDesde, fechaHasta, tipoCotizacion, codigo);

                result.Columns.Add("idCotizacion", Type.GetType("System.String"));
                result.Columns.Add("idCotizacionDetalle", Type.GetType("System.String"));
                result.Columns.Add("codigoCotizacion", Type.GetType("System.String"));
                result.Columns.Add("nombrecliente", Type.GetType("System.String"));
                result.Columns.Add("obra", Type.GetType("System.String"));
                result.Columns.Add("referencia", Type.GetType("System.String"));
                result.Columns.Add("fechaRegistro", Type.GetType("System.String"));
                result.Columns.Add("esAlquiler", Type.GetType("System.String"));
                result.Columns.Add("esVenta", Type.GetType("System.String"));
                result.Columns.Add("secuencia", Type.GetType("System.String"));
                result.Columns.Add("codigoEquipo", Type.GetType("System.String"));
                result.Columns.Add("nombreEquipo", Type.GetType("System.String"));
                result.Columns.Add("moneda", Type.GetType("System.String"));
                result.Columns.Add("horaTarifa", Type.GetType("System.String"));
                result.Columns.Add("tipoTarifa", Type.GetType("System.String"));
                result.Columns.Add("montoTarifa", Type.GetType("System.String"));
                result.Columns.Add("tarifa", Type.GetType("System.String"));
                result.Columns.Add("dscto", Type.GetType("System.String"));
                result.Columns.Add("impuestos", Type.GetType("System.String"));
                result.Columns.Add("tarifaTotal", Type.GetType("System.String"));

                DataRow dr;

                foreach (var c in query)
                {
                    dr = result.NewRow();

                    dr[0] = c.idCotizacion;
                    dr[1] = c.idCotizacionDetalle;
                    dr[2] = c.codigoCotizacion;
                    dr[3] = c.nombrecliente.Trim();
                    dr[4] = c.obra;
                    dr[5] = c.referencia.Trim();
                    dr[6] = c.fechaRegistro.HasValue ? c.fechaRegistro.Value.ToShortDateString() : string.Empty;
                    dr[7] = c.esAlquiler;
                    dr[8] = c.esVenta;
                    dr[9] = c.secuencia;
                    dr[10] = c.codigoEquipo;
                    dr[11] = c.nombreEquipo;
                    dr[12] = c.moneda;
                    dr[13] = c.horaTarifa;
                    dr[14] = c.tipoTarifa;
                    dr[15] = c.montoTarifa.HasValue ? c.montoTarifa.Value.ToString("N2") : string.Empty;
                    dr[16] = c.tarifa.HasValue ? c.tarifa.Value.ToString("N2") : string.Empty;
                    dr[17] = c.dscto.HasValue ? c.dscto.Value.ToString("N2"): string.Empty;
                    dr[18] = c.impuestos.HasValue ? c.impuestos.Value.ToString("N2") : string.Empty;
                    dr[19] = c.tarifaTotal.HasValue ? c.tarifaTotal.Value.ToString("N2") : string.Empty;

                    result.Rows.Add(dr);
                }
                
                return result;
            }
        }
    }
}
